package cn.kivensoft.xlsx.reader;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class Utilities {
	private static final long DAY_MILLISECONDS = 24 * 60 * 60 * 1000;

	private static final ThreadLocal<Calendar> calendar = new ThreadLocal<Calendar>() {
		@Override
		protected Calendar initialValue() {
			return Calendar.getInstance();
		}
	};

	private static final ThreadLocal<DateFormat> sdfDate = new ThreadLocal<DateFormat>() {
		@Override
		protected DateFormat initialValue() {
			return new SimpleDateFormat("yyyy-MM-dd");
		}
	};

	private static final ThreadLocal<DateFormat> sdfTime = new ThreadLocal<DateFormat>() {
		@Override
		protected DateFormat initialValue() {
			return new SimpleDateFormat("HH:mm:ss");
		}
	};

	private static final ThreadLocal<DateFormat> sdfDateTime = new ThreadLocal<DateFormat>() {
		@Override
		protected DateFormat initialValue() {
			return new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
		}
	};

	public static Date strToDate(String dateStr) {
		try {
			return sdfDate.get().parse(dateStr);
		} catch (Exception e) {
			return null;
		}
	}
	
	public static Date strToTime(String timeStr) {
		try {
			return sdfTime.get().parse(timeStr);
		} catch (Exception e) {
			return null;
		}
	}
	
	public static Date strToDateTime(String dateTimeStr) {
		try {
			return sdfDateTime.get().parse(dateTimeStr);
		} catch (Exception e) {
			return null;
		}
	}
	
	public static Date toDate(String excelDate, int baseYear) {
		Calendar cal = calendar.get();
		cal.set(baseYear, 0, 1, 0, 0, 0);
		cal.set(Calendar.MILLISECOND, 0);
		try {
			int mc = baseYear == 1900 ? 2 : 0;
			int daysToAdd = (int) Math.floor(Double.parseDouble(excelDate));
			cal.add(Calendar.DATE, daysToAdd - mc);
			return cal.getTime();
		} catch (Exception e) {
			return null;
		}
	}

	public static String convertDate(String excelDate, int baseYear) {
		Date d = toDate(excelDate, baseYear);
		return d == null ? null : sdfDate.get().format(d);
	}

	public static Date toTime(String excelTime) {
		Calendar cal = calendar.get();
		cal.clear();
		try {
			double time = Double.parseDouble(excelTime);
			double second = 1 / 86400d;
			int seconds = (int) Math.floor(time / second);
			cal.add(Calendar.SECOND, seconds);
			return cal.getTime();
		} catch (Exception e) {
			return null;
		}
	}

	public static String convertTime(String excelTime) {
		Date t = toTime(excelTime);
		return t == null ? null : sdfTime.get().format(t);
	}

	public static Date toDateTime(String excelDateTime, int baseYear) {
		Calendar cal = calendar.get();
		cal.set(baseYear, 0, 1, 0, 0, 0);
		cal.set(Calendar.MILLISECOND, 0);
		try {
			int mc = baseYear == 1900 ? 2 : 0;
			double d = Double.parseDouble(excelDateTime);
			int daysToAdd = (int) Math.floor(d);
			cal.add(Calendar.DATE, daysToAdd - mc);
			cal.add(Calendar.MILLISECOND, (int) ((d - daysToAdd)
					* DAY_MILLISECONDS + 0.5));
			return cal.getTime();
		} catch (Exception e) {
			return null;
		}
	}

	public static String convertDateTime(String excelDateTime, int baseYear) {
		Date d = toDateTime(excelDateTime, baseYear);
		return d == null ? null : sdfDateTime.get().format(d);
	}

}
